1
/****************************** Module Header ******************************\
2 * Module Name: DownloaderHelper.cs
3 * Project: CSWebDownloader
4 * Copyright (c) Microsoft Corporation.
6 * This class supplies the methods to
7 * 1. Initialize a HttpWebRequest object.
8 * 2. Check the url and initialize some properties of a downloader.
9 * 3. Check whether the destination file exists. If not, create a file with
10 * the same size as the file to be downloaded.
13 * This source is subject to the Microsoft Public License.
14 * See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
15 * All other rights reserved.
17 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
18 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
20 \***************************************************************************/
24 using System
.Text
.RegularExpressions
;
27 namespace CSWebDownloader
29 public static class DownloaderHelper
32 public static HttpWebRequest
InitializeHttpWebRequest(IDownloader downloader
)
34 var webRequest
= (HttpWebRequest
)WebRequest
.Create(downloader
.Url
);
36 if (downloader
.Credentials
!= null)
38 webRequest
.Credentials
= downloader
.Credentials
;
42 webRequest
.Credentials
= CredentialCache
.DefaultCredentials
;
45 if (downloader
.Proxy
!= null)
47 webRequest
.Proxy
= downloader
.Proxy
;
51 webRequest
.Proxy
= WebRequest
.DefaultWebProxy
;
58 /// Check the URL to download, including whether it supports Range,
60 /// <param name="downloader"></param>
61 /// <returns></returns>
62 public static string CheckUrl(IDownloader downloader
)
64 string fileName
= string.Empty
;
66 // Check the file information on the remote server.
67 var webRequest
= InitializeHttpWebRequest(downloader
);
69 using (var response
= webRequest
.GetResponse())
71 foreach (var header
in response
.Headers
.AllKeys
)
73 if (header
.Equals("Accept-Ranges", StringComparison
.OrdinalIgnoreCase
))
75 downloader
.IsRangeSupported
= true;
78 if (header
.Equals("Content-Disposition", StringComparison
.OrdinalIgnoreCase
))
80 string contentDisposition
= response
.Headers
[header
];
82 string pattern
= ".[^;]*;\\s+filename=\"(?<file>.*)\"";
83 Regex r
= new Regex(pattern
);
84 Match m
= r
.Match(contentDisposition
);
87 fileName
= m
.Groups
["file"].Value
;
92 downloader
.TotalSize
= response
.ContentLength
;
94 if (downloader
.TotalSize
<= 0)
96 throw new ApplicationException(
97 "The file to download does not exist!");
100 if (!downloader
.IsRangeSupported
)
102 downloader
.StartPoint
= 0;
103 downloader
.EndPoint
= int.MaxValue
;
107 if (downloader
.IsRangeSupported
&&
108 (downloader
.StartPoint
!= 0 || downloader
.EndPoint
!= long.MaxValue
))
110 webRequest
= InitializeHttpWebRequest(downloader
);
112 if (downloader
.EndPoint
!= int.MaxValue
)
114 webRequest
.AddRange(downloader
.StartPoint
, downloader
.EndPoint
);
118 webRequest
.AddRange(downloader
.StartPoint
);
120 using (var response
= webRequest
.GetResponse())
122 downloader
.TotalSize
= response
.ContentLength
;
131 /// Check whether the destination file exists. If not, create a file with the same
132 /// size as the file to be downloaded.
134 public static void CheckFileOrCreateFile(IDownloader downloader
, object fileLocker
)
136 // Lock other threads or processes to prevent from creating the file.
139 FileInfo fileToDownload
= new FileInfo(downloader
.DownloadPath
);
140 if (fileToDownload
.Exists
)
143 // The destination file should have the same size as the file to be downloaded.
144 if (fileToDownload
.Length
!= downloader
.TotalSize
)
146 throw new ApplicationException(
147 "The download path already has a file which does not match"
148 + " the file to download. ");
155 if (downloader
.TotalSize
== 0)
157 throw new ApplicationException("The file to download does not exist!");
160 using (FileStream fileStream
= File
.Create(downloader
.DownloadPath
))
162 long createdSize
= 0;
163 byte[] buffer
= new byte[4096];
164 while (createdSize
< downloader
.TotalSize
)
166 int bufferSize
= (downloader
.TotalSize
- createdSize
) < 4096
167 ? (int)(downloader
.TotalSize
- createdSize
) : 4096;
168 fileStream
.Write(buffer
, 0, bufferSize
);
169 createdSize
+= bufferSize
;